package cn.xtits.xtp.controller;

import cn.xtits.xtf.common.utils.JsonUtil;
import cn.xtits.xtf.common.utils.MapperUtil;
import cn.xtits.xtf.common.web.AjaxResult;
import cn.xtits.xtf.common.web.Pagination;
import cn.xtits.xtp.dto.AreaDto;
import cn.xtits.xtp.entity.Area;
import cn.xtits.xtp.entity.AreaExample;
import cn.xtits.xtp.service.AreaService;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @fileName: AreaController.java
 * @author: Dan
 * @createDate: 2018-02-28 13:43:14
 * @description: 地区表
 */
@RestController
@RequestMapping("/area")
public class AreaController extends BaseController {


    Gson gson = new GsonBuilder().serializeNulls().create();

    @Autowired
    private AreaService service;

    @RequiresPermissions("ibasic-area:insert")
    @RequestMapping(value = "insertArea")
    public AjaxResult insertArea(
            @RequestParam(value = "data", required = false) String data) {

        List<Area> list = gson.fromJson(data, new TypeToken<List<Area>>() {
        }.getType());

        Area record = JsonUtil.fromJson(data, Area.class);
        if (exist(record) > 0) {
            return new AjaxResult(-1, "地区:" + record.getName() + ",已存在");
        }
        //Date dt = getDateNow();
        record.setCreateDate(null);
        record.setMakeBillMan(getUserName());
        record.setModifier(getUserName());
        record.setModifyDate(null);
        record.setDeleteFlag(false);
        service.insert(record);
        return new AjaxResult(record);
    }

    @RequiresPermissions("ibasic-area:delete")
    @RequestMapping(value = "deleteArea")
    public AjaxResult deleteArea(
            @RequestParam(value = "id", required = false) int id) {
        {
            AreaExample example = new AreaExample();
            example.setPageSize(1);
            AreaExample.Criteria criteria = example.createCriteria();
            criteria.andDeleteFlagEqualTo(false);
            criteria.andParentIdEqualTo(id);
            if (service.listByExample(example).size() > 0) {
                return new AjaxResult(-1, "存在子节点");
            }
        }
        Area record = new Area();
        record.setId(id);
        record.setDeleteFlag(true);
        record.setModifier(getUserName());
        record.setModifyDate(null);
        int row = service.updateByPrimaryKeySelective(record);
        return new AjaxResult(row);
    }

    @RequiresPermissions("ibasic-area:update")
    @RequestMapping(value = "updateArea")
    public AjaxResult updateArea(
            @RequestParam(value = "data", required = false) String data) {
        Area record = JsonUtil.fromJson(data, Area.class);
        if (exist(record) > 0) {
            return new AjaxResult(-1, "地区:" + record.getName() + ",已存在");
        }
        record.setCreateDate(null);
        record.setMakeBillMan(null);
        record.setModifyDate(null);
        record.setModifier(getUserName());
        record.setDeleteFlag(false);
        service.updateByPrimaryKeySelective(record);
        return new AjaxResult(record);
    }

    //@RequiresPermissions("ibasic-area:list")
    @RequestMapping(value = "listArea")
    public AjaxResult listArea(
            @RequestParam(value = "parentId", required = false) Integer parentId,
            @RequestParam(value = "code", required = false) String code,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "levels", required = false) Integer levels,
            @RequestParam(value = "leafFlag", required = false) Boolean leafFlag,
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
            @RequestParam(value = "orderBy", required = false) String orderBy,
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate) {
        DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        AreaExample example = new AreaExample();
        example.setPageIndex(pageIndex);
        example.setPageSize(pageSize);
        if (StringUtils.isNotBlank(orderBy)) {
            example.setOrderByClause(orderBy);
        }
        AreaExample.Criteria criteria = example.createCriteria();

        criteria.andDeleteFlagEqualTo(false);
        if (parentId != null) {
            criteria.andParentIdEqualTo(parentId);
        }
        if (StringUtils.isNotBlank(code)) {
            criteria.andCodeLike(code);
        }
        if (StringUtils.isNotBlank(name)) {
            criteria.andNameLike(name);
        }
        if (levels != null) {
            criteria.andLevelEqualTo(levels);
        }
        if (leafFlag != null) {
            criteria.andLeafFlagEqualTo(leafFlag);
        }
        if (StringUtils.isNotBlank(startDate)) {
            criteria.andCreateDateGreaterThanOrEqualTo(DateTime.parse(startDate, format).toDate());
        }
        if (StringUtils.isNotBlank(endDate)) {

            criteria.andCreateDateLessThanOrEqualTo(DateTime.parse(endDate, format).toDate());
        }

        List<Area> list = service.listByExample(example);
        Pagination<Area> pList = new Pagination<>(example, list, example.getCount());
        return new AjaxResult(pList);
    }

    @RequestMapping(value = "getArea")
    public AjaxResult getArea(@RequestParam(value = "id", required = false) Integer id) {
        Area res = service.getByPrimaryKey(id);
        return new AjaxResult(res);
    }

    /**
     * 树型结构
     *
     * @return
     */
    @RequestMapping(value = "listAreaTree")
    public AjaxResult listAreaTree() {
        AreaExample example = new AreaExample();
        example.setPageSize(Integer.MAX_VALUE);
        AreaExample.Criteria criteria = example.createCriteria();
        criteria.andDeleteFlagEqualTo(false);
        List<Area> list = service.listByExample(example);
        List<AreaDto> arrayList = new ArrayList<>();
        for (Area area : list) {
            AreaDto areaDto = new AreaDto();
            MapperUtil.copyProperties(area, areaDto);
            arrayList.add(areaDto);
        }
        List<AreaDto> treeChildRecord = getTreeChildRecord(arrayList, 0);

        return new AjaxResult(treeChildRecord);
    }

    /**
     * 说明方法描述：递归查询子节点
     *
     * @param allList  所有节点
     * @param parentId 父节点id
     * @time 2017-9-26
     * @author Dan
     */
    private List<AreaDto> getTreeChildRecord(List<AreaDto> allList, Integer parentId) {
        List<AreaDto> listParentRecord = new ArrayList<>();
        List<AreaDto> listNotParentRecord = new ArrayList<>();
        // allList，找出所有的根节点和非根节点
        if (allList != null && allList.size() > 0) {
            for (AreaDto record : allList) {
                // 对比找出父节点
                if (record.getParentId().equals(parentId)) {
                    listParentRecord.add(record);
                } else {
                    listNotParentRecord.add(record);
                }
            }
        }
        // 查询子节点
        if (listParentRecord.size() > 0) {
            for (AreaDto record : listParentRecord) {
                // 递归查询子节点
                record.setChildren(getTreeChildRecord(listNotParentRecord, record.getId()));
            }
        }
        return listParentRecord;
    }

    private int exist(Area entity) {
        AreaExample example = new AreaExample();
        example.setPageSize(1);
        AreaExample.Criteria criteria = example.createCriteria();
        criteria.andDeleteFlagEqualTo(false);
        if (null != entity.getId() && entity.getId() > 0) {
            criteria.andIdNotEqualTo(entity.getId());
        }
        criteria.andNameEqualTo(entity.getName());
        return service.listByExample(example).size();
    }

}